﻿Option Explicit On
Imports System.IO

Public Module modSection

    Public Class KeyValue

        Public Structure INISection
            Public SectionName As String
            Public SectionContext As String
        End Structure

        Public Structure Cite
            Public SectionName As String
            Public LineIndex As Integer()
            Public LineContext As String()
        End Structure

        Public Structure INILineWord
            Public WordContext As String
            Public LineType As String
        End Structure

        Public Structure INICodeData
            Public CodeName As ArrayList
            Public CodeMean As ArrayList
        End Structure

        Public Sub New()

        End Sub

        Public Function ReadToArray(ByVal RText As RichTextBox) As Collections.Generic.Dictionary(Of String, System.Collections.Generic.Dictionary(Of String, Object))
            Dim KeyValueCollection As New Collections.Generic.Dictionary(Of String, System.Collections.Generic.Dictionary(Of String, Object))
            Dim mCurrentRoot As String = Nothing

            Dim tmpCStr As String

            For Each line As String In RText.Lines 'Form1.RichTextBox1.Lines 'System.IO.File.ReadAllLines(txtFile, System.Text.Encoding.Default)

                'tmpCStr = line
                'tmpCStr = tmpCStr.Replace("" & Chr(9) & "", " ")
                tmpCStr = Trim(line.Split(";")(0))
                tmpCStr = Trim(tmpCStr.Split(Chr(9))(0))

                If tmpCStr.StartsWith("[") AndAlso tmpCStr.EndsWith("]") Then
                    mCurrentRoot = Trim(line.Split(";")(0)).Substring(1, tmpCStr.Length - 2)
                    Try
                        KeyValueCollection.Add(mCurrentRoot, New System.Collections.Generic.Dictionary(Of String, Object))
                    Catch ex As Exception

                    End Try
                End If

            Next

            ReadToArray = KeyValueCollection
        End Function

        Public Function GetSectionArray(ByVal RText As RichTextBox) As String()
            Dim exp As String()
            ReDim Preserve exp(0)

            For Each root As String In ReadToArray(RText).Keys
                ReDim Preserve exp(UBound(exp) + 1)
                exp(UBound(exp)) = root
            Next

            GetSectionArray = exp
        End Function

        Public Function GetSectionArrayFromFile(ByVal Path As String, ByVal tmpRTF As RichTextBox) As String()
            If System.IO.File.Exists(Path) = False Then Exit Function
            Dim fs As New System.IO.FileStream(Path, IO.FileMode.Open)
            Dim sr As New System.IO.StreamReader(fs)
            'Dim strTemp As String
            tmpRTF.Text = sr.ReadToEnd
            sr.Close()
            fs.Close()

            Dim exp As String()
            ReDim Preserve exp(0)

            For Each root As String In ReadToArray(tmpRTF).Keys
                ReDim Preserve exp(UBound(exp) + 1)
                exp(UBound(exp)) = root
            Next

            GetSectionArrayFromFile = exp
        End Function

        Public Function GetSectionContextArrayFromFile(ByVal Path As String, ByVal tmpRTF As RichTextBox) As INISection()
            Dim cuLine As String = ""
            Dim SectionText As String = ""

            Dim fs As New System.IO.FileStream(Path, IO.FileMode.Open)
            Dim sr As New System.IO.StreamReader(fs, System.Text.Encoding.GetEncoding("GB2312"))
            'Dim strTemp As String
            tmpRTF.Text = sr.ReadToEnd
            'tmpRTF.Text = tmpRTF.Text.Replace("" & Chr(9) & "", " ")
            'tmpRTE = sr.ReadToEnd
            sr.Close()
            fs.Close()
            'Dim sw As StreamWriter = New StreamWriter(Path)
            'sw.Write(tmpRTE.Replace("" & Chr(9) & "", " "))
            'sw.Close()


            Dim exp As INISection()
            Dim defSecArray As Collections.Generic.Dictionary(Of String, System.Collections.Generic.Dictionary(Of String, Object)) = ReadToArray(tmpRTF)
            'ReDim Preserve exp(0)
            fs = New System.IO.FileStream(Path, IO.FileMode.Open)
            sr = New System.IO.StreamReader(fs, System.Text.Encoding.GetEncoding("GB2312"))

            'tmpRTF.Text = sr.ReadToEnd
            'tmpRTF.Text = tmpRTF.Text.Replace("" & Chr(9) & "", " ")
            For Each root As String In defSecArray.Keys 'ReadToArray(tmpRTF).Keys
                SectionText = ""
                cuLine = ""
                If exp Is Nothing Then
                    ReDim Preserve exp(0)
                Else
                    ReDim Preserve exp(UBound(exp) + 1)
                End If
                exp(UBound(exp)).SectionName = root

                'While Microsoft.VisualBasic.Left(cuLine, Trim(root).Length + 2) <> "[" & Trim(root) & "]"
                'cuLine = sr.ReadLine
                'End While
                'cuLine = sr.ReadLine
                If root = GetFirstSectionName(defSecArray) Then
                    While Microsoft.VisualBasic.Left(cuLine, 1) <> "[" Or Trim(Microsoft.VisualBasic.Left(cuLine, root.Length + 2)) = "[" + root + "]"
                        If SectionText = "" Then
                            SectionText = cuLine
                            cuLine = sr.ReadLine
                        Else
                            SectionText = SectionText + vbCrLf + cuLine
                            'SectionText = SectionText + vbLf + cuLine
                            cuLine = sr.ReadLine
                        End If
                    End While

                    exp(UBound(exp)).SectionContext = SectionText
                Else
                    While Microsoft.VisualBasic.Left(cuLine, 1) <> "[" And sr.Peek() >= 0 Or Trim(Microsoft.VisualBasic.Left(cuLine, root.Length + 2)) = "[" + root + "]"

                        'If cuLine <> Nothing Then
                        If SectionText = "" Then
                            SectionText = cuLine
                            cuLine = sr.ReadLine
                        Else
                            SectionText = SectionText + vbCrLf + cuLine
                            'SectionText = SectionText + vbLf + cuLine
                            cuLine = sr.ReadLine
                        End If
                        ' Else
                        'Exit While
                        'End If

                    End While

                    'exp(UBound(exp)).SectionContext = SectionText
                    exp(UBound(exp)).SectionContext = "[" + root + "]" + vbCrLf + SectionText
                    'exp(UBound(exp)).SectionContext = "[" + root + "]" + vbLf + SectionText
                    Application.DoEvents()
                End If

            Next

            sr.Close()
            fs.Close()

            GetSectionContextArrayFromFile = exp
        End Function

        Public Function RefreshSectionToFile(ByVal Section As INISection(), ByVal FileName As String) As String
            Dim wStr As String = ""

            For Each unitSec In Section

                If wStr = "" Then

                    unitSec.SectionContext = Replace(unitSec.SectionContext, "DisableAIParallelProduction", "FalseConversion", , , CompareMethod.Text)
                    unitSec.SectionContext = Replace(unitSec.SectionContext, "EnableAIBuildLimitation", "FalseConversion", , , CompareMethod.Text)
                    unitSec.SectionContext = Replace(unitSec.SectionContext, "MindControllerGainExperienceRatio", "FalseConversion", , , CompareMethod.Text)
                    unitSec.SectionContext = Replace(unitSec.SectionContext, "PrismSupportDelayVeteran", "FalseConversion", , , CompareMethod.Text)
                    unitSec.SectionContext = Replace(unitSec.SectionContext, "PrismSupportDelayElite", "FalseConversion", , , CompareMethod.Text)
                    unitSec.SectionContext = Replace(unitSec.SectionContext, "AIIonCannonSpecialOneValue", "FalseConversion", , , CompareMethod.Text)
                    unitSec.SectionContext = Replace(unitSec.SectionContext, "AIIonCannonSpecialTwoValue", "FalseConversion", , , CompareMethod.Text)
                    unitSec.SectionContext = Replace(unitSec.SectionContext, "AIIonCannonSpecialTwoValue", "FalseConversion", , , CompareMethod.Text)
                    unitSec.SectionContext = Replace(unitSec.SectionContext, "AIIonCannonSpecialThreeValue", "FalseConversion", , , CompareMethod.Text)

                    wStr = wStr + unitSec.SectionContext
                Else
                    If unitSec.SectionName = "AudioVisual" Then
                        unitSec.SectionContext = Replace(unitSec.SectionContext, "DecloakSound", "FalseConversion", , , CompareMethod.Text)
                        wStr = wStr + vbCrLf + unitSec.SectionContext
                        'wStr = wStr + vbLf + unitSec.SectionContext
                        'ElseIf InStr(unitSec.SectionContext, "TrueConversion", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "TrainPassengers", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "EMPHardened", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "IsCyclicGattling", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "UseROFAsBurstDelays", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "PrismSupportDelayVeteran", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "PrismSupportDelayElite", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "WeaponShakeYlo", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "WeaponShakeYhi", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "WeaponShakeXhi", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "WeaponShakeXlo", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "ScatterRadius", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "AIBasePlanningCount", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "AISWTargetingSpecialValue", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "SuppressesInfantryDeathWeapon", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "IsFlatExplosion", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "UseRippleEffect", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "AlternateOnWaterArt", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "BunkerPenetrationLevel", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "BunkerProtectionLevel", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "DoesntAffectEnemies", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "TurretROT", CompareMethod.Text) <= 0 Then
                    ElseIf InStr(unitSec.SectionContext, "TrueConversion", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "TrainPassengers", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "EMPHardened", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "IsCyclicGattling", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "UseROFAsBurstDelays", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "PrismSupportDelayVeteran", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "PrismSupportDelayElite", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "WeaponShakeYlo", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "WeaponShakeYhi", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "WeaponShakeXhi", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "WeaponShakeXlo", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "ScatterRadius", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "AIBasePlanningCount", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "AISWTargetingSpecialValue", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "SuppressesInfantryDeathWeapon", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "IsFlatExplosion", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "UseRippleEffect", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "AlternateOnWaterArt", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "BunkerPenetrationLevel", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "BunkerProtectionLevel", CompareMethod.Text) <= 0 And InStr(unitSec.SectionContext, "DoesntAffectEnemies", CompareMethod.Text) <= 0 Then
                        wStr = wStr + vbCrLf + unitSec.SectionContext
                        'wStr = wStr + vbLf + unitSec.SectionContext
                    End If
                End If

            Next

            Dim sw As StreamWriter = New StreamWriter(FileName, False, System.Text.Encoding.GetEncoding("GB2312"))
            sw.Write(wStr)
            sw.Close()

            RefreshSectionToFile = wStr
        End Function

        Public Function SearchInArray(ByVal SectionArray As INISection(), ByVal curIndex As Integer, ByVal strFind As String, ByVal IsNext As Boolean) As Integer
            Dim ub As Integer = UBound(SectionArray)
            Dim searchIn As Integer = -1

            If curIndex <= ub Then
                If IsNext = True Then

                    For i = curIndex + 1 To ub
                        If InStr(SectionArray(i).SectionContext, strFind, CompareMethod.Text) <> 0 Then
                            searchIn = i
                            Exit For
                        End If
                    Next

                ElseIf IsNext = False Then

                    For i = curIndex - 1 To 0 Step -1
                        If InStr(SectionArray(i).SectionContext, strFind, CompareMethod.Text) <> 0 Then
                            searchIn = i
                            Exit For
                        End If
                    Next

                End If
            End If

            SearchInArray = searchIn
        End Function

        Public Function InsertSection(ByVal Array As INISection(), ByVal Index As Integer, ByVal Title As String) As INISection()

            Dim tmpArray As INISection()
            'Dim tmpInt1 As Integer
            'tmpArray = Array
            ReDim Preserve tmpArray(Array.Length)

            For i = 0 To Index
                tmpArray(i).SectionName = Array(i).SectionName
                tmpArray(i).SectionContext = Array(i).SectionContext
            Next

            For i = Index + 1 To Array.Length
                'tmpInt1 = i - 1
                tmpArray(i).SectionName = Array(i - 1).SectionName
                tmpArray(i).SectionContext = Array(i - 1).SectionContext
            Next

            tmpArray(Index).SectionName = Title
            tmpArray(Index).SectionContext = "[" + Title + "]" + vbCrLf  '待修改
            'tmpArray(Index).SectionContext = "[" + Title + "]" + vbLf  '待修改

            Return tmpArray

        End Function

        Public Function GetSectionContextFormName(ByVal Array As INISection(), ByVal SectionName As String) As String

            For Each Section In Array
                If Section.SectionName = SectionName Then
                    Return Section.SectionContext
                    Exit For
                    Exit Function
                End If
            Next

            Return "SYSTEM:NOTHING"

        End Function

        Public Function GetSectionIndexFormName(ByVal Array As INISection(), ByVal SectionName As String) As String

            For i = 0 To UBound(Array)
                If Array(i).SectionName = SectionName Then
                    Return i
                    Exit For
                End If
            Next

        End Function

        Public Function ExistsSection(ByVal Array As INISection(), ByVal SectionName As String) As Boolean

            For Each Section In Array
                If Section.SectionName = SectionName Then
                    Return True
                    Exit Function
                    Exit For
                End If
            Next

            Return False

        End Function

        Public Function DeleteSection(ByVal Array As INISection(), ByVal Index As Integer) As INISection()

            Dim tmpArray As INISection()
            'Dim tmpInt1 As Integer
            'tmpArray = Array
            ReDim Preserve tmpArray(Array.Length - 2)

            For i = 0 To Index - 1
                tmpArray(i).SectionName = Array(i).SectionName
                tmpArray(i).SectionContext = Array(i).SectionContext
            Next

            For i = Index + 1 To UBound(tmpArray)
                tmpArray(i).SectionName = Array(i + 1).SectionName
                tmpArray(i).SectionContext = Array(i + 1).SectionContext
            Next

            Return tmpArray

        End Function

        Private Function GetFirstSectionName(ByVal cColl As Collections.Generic.Dictionary(Of String, System.Collections.Generic.Dictionary(Of String, Object))) As String

            For Each root As String In cColl.Keys
                GetFirstSectionName = root
                Exit For
            Next

        End Function

    End Class

End Module
